﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.UserData;
using System.Diagnostics;
using SMSHelper.Helper;
using SMSHelper.Data;
using System.Threading;
using Microsoft.Phone.Shell;

namespace SMSHelper
{
    public partial class MainPage : PhoneApplicationPage
    {
        #region member variable
        /// <summary>
        /// data source
        /// </summary>
        List<PhoneNumberInfo> smsContacts;
        /// <summary>
        /// load data thread
        /// </summary>
        Thread _loadThread;
        #endregion

        #region constructor
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainPage_Loaded);
        }
        #endregion

        #region private method
        /// <summary>
        /// load data ,first from database, second from contacts
        /// </summary>
        void LoadData()
        {
            Invoke(() => spLoding.Visibility = System.Windows.Visibility.Visible);
            smsContacts = DataProvider.GetAllNumber();
            if (smsContacts != null && smsContacts.FirstOrDefault() != null)
            {
                var phonNumberByTitle = from number in smsContacts group number by number.GroupTitle into c orderby c.Key select new Group<PhoneNumberInfo>(c.Key, c);
                Invoke(() => longList.DataContext = phonNumberByTitle);
                Invoke(() => spLoding.Visibility = System.Windows.Visibility.Collapsed);
            }
            else
            {
                GetNewNumbers();
            }
        }

        void Invoke(Action a)
        {
            this.Dispatcher.BeginInvoke(a);
        }

        /// <summary>
        /// get from contacts
        /// </summary>
        void GetNewNumbers()
        {
            Microsoft.Phone.UserData.Contacts contacts = new Microsoft.Phone.UserData.Contacts();
            contacts.SearchCompleted += new EventHandler<Microsoft.Phone.UserData.ContactsSearchEventArgs>(contacts_SearchCompleted);
            contacts.SearchAsync("*", Microsoft.Phone.UserData.FilterKind.None, null);
        }
        #endregion

        #region event handle
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            _loadThread = new Thread(new ThreadStart(LoadData));
            _loadThread.IsBackground = true;
            _loadThread.Start();

            #region update mui
            var btns = ApplicationBar.Buttons.OfType<ApplicationBarIconButton>();
            if (btns != null)
            {
                foreach (var btn in btns)
                {
                    if (btn.Text == "SendMsg")
                        btn.Text = AppResources.SendMsg;
                    else if (btn.Text == "ClearAll")
                        btn.Text = AppResources.ClearAll;
                }
            }

            var menus = ApplicationBar.MenuItems.OfType<ApplicationBarMenuItem>();
            if (menus != null)
            {
                foreach (var menu in menus)
                {
                    if (menu.Text == "UpdateContacts")
                        menu.Text = AppResources.UpdateContacts;
                    else if (menu.Text == "Help")
                        menu.Text = AppResources.Help;
                }
            }

            #endregion
        }

        void contacts_SearchCompleted(object sender, Microsoft.Phone.UserData.ContactsSearchEventArgs e)
        {
            IEnumerable<Contact> contacts = e.Results;

            smsContacts = new List<PhoneNumberInfo>();
            foreach (Contact _contact in contacts)
            {
                foreach (ContactPhoneNumber _number in _contact.PhoneNumbers)
                {
                    if (smsContacts.Any(o => o.PersonName == _contact.DisplayName && o.PhoneNumber == _number.PhoneNumber))
                        continue;
                    smsContacts.Add(new PhoneNumberInfo()
                    {
                        PhoneNumber = _number.PhoneNumber,
                        PersonName = _contact.DisplayName,
                        GroupTitle = SpellCodeHelper.GetChineseSpell(_contact.DisplayName)
                    });
                }
            }
            var phonNumberByTitle = from smsContract in smsContacts group smsContract by smsContract.GroupTitle into c orderby c.Key select new Group<PhoneNumberInfo>(c.Key, c);
            Invoke(() => longList.DataContext = phonNumberByTitle);
            Invoke(() => spLoding.Visibility = System.Windows.Visibility.Collapsed);
            DataProvider.InitNumbers(smsContacts);
        }

        private void miDeleteAll_Click(object sender, EventArgs e)
        {
            DataProvider.DeleteAllNumbers();
        }

        private void chk_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
        {
            CheckBox chk = sender as CheckBox;
            var tts = chk.RenderTransform as TranslateTransform;
            tts.X = 4;
            tts.Y = 4;
        }

        private void chk_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
        {
            CheckBox chk = sender as CheckBox;
            var tts = chk.RenderTransform as TranslateTransform;
            tts.X = 0;
            tts.Y = 0;
        }

        private void miUpdateNumber_Click(object sender, EventArgs e)
        {
            DataProvider.DeleteAllNumbers();
            longList.DataContext = null;
            if (_loadThread != null && _loadThread.IsAlive) return;
            _loadThread = new Thread(new ThreadStart(LoadData));
            _loadThread.IsBackground = true;
            _loadThread.Start();
        }

        private void btnGoNext_Click(object sender, EventArgs e)
        {
            var checkedItems = smsContacts.Where(o => o.IsChecked).ToList();
            string format = "{0}<{1}>";
            var numberArray = checkedItems.Select(o => string.Format(format, o.PersonName, o.PhoneNumber)).ToArray();
            var numbers = string.Join(";", numberArray);

            Microsoft.Phone.Tasks.SmsComposeTask task = new Microsoft.Phone.Tasks.SmsComposeTask();
            task.To = numbers;
            task.Show();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            var checkedItems = smsContacts.Where(o => o.IsChecked);
            foreach (var item in checkedItems)
            {
                item.IsChecked = false;
            }
        }

        private void miHelp_Click(object sender, EventArgs e)
        {
            MessageBox.Show(AppResources.HelpContent);
        }
        #endregion


    }

    public class Group<T> : IEnumerable<T>
    {
        public Group(string name, IEnumerable<T> items)
        {
            this.Title = name;
            this.Items = new List<T>(items);
        }

        public override bool Equals(object obj)
        {
            Group<T> that = obj as Group<T>;

            return (that != null) && (this.Title.Equals(that.Title));
        }

        public string Title
        {
            get;
            set;
        }

        public IList<T> Items
        {
            get;
            set;
        }

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            return this.Items.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.Items.GetEnumerator();
        }

        #endregion

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}